package com.tarena.lbs.basic.web.service.impl;

import com.tarena.lbs.pojo.basic.param.EsUpdateParam;
import java.io.IOException;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class EsClientUtils {

    @Resource
    private RestHighLevelClient restHighLevelClient;

    public boolean insertData(EsUpdateParam dto, String source) {
        //指定索引库名称进行操作
        IndexRequest indexRequest = new IndexRequest(dto.getIndexName());
        indexRequest.source(source, XContentType.JSON);
        if (dto.getId() != null) {
            indexRequest.id(String.valueOf(dto.getId()));
        }
        try {
            restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.info("插入{}数据出现异常: {}", dto.getIndexName(), e);
            return false;
        }
        return true;
    }

    /**
     * 创建索引(默认分片数为5和副本数为1)
     *
     * @param clazz 根据实体自动映射es索引
     * @throws IOException
     */
    public boolean createIndex(Class clazz) {
        try {
            Document declaredAnnotation = (Document) clazz.getDeclaredAnnotation(Document.class);
            String indexName = declaredAnnotation.indexName();
            CreateIndexRequest request = new CreateIndexRequest(indexName);
            request.settings(Settings.builder()
                // 设置分片数为3， 副本为2
                .put("index.number_of_shards", 3)
                .put("index.number_of_replicas", 2)
            );
            CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
            // 指示是否所有节点都已确认请求
            boolean acknowledged = response.isAcknowledged();
            // 指示是否在超时之前为索引中的每个分片启动了必需的分片副本数
            boolean shardsAcknowledged = response.isShardsAcknowledged();
            if (acknowledged || shardsAcknowledged) {
                log.info("创建索引成功！索引名称为{}", indexName);
                return true;
            }
        } catch (Exception e) {
            log.info("创建索引出现异常: {}", e);
        }
        return false;
    }

    public boolean deleteIndex(String indexName) {
        try {
            DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indexName);
            AcknowledgedResponse acknowledgedResponse = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
            return acknowledgedResponse.isAcknowledged();
        } catch (Exception e) {
            log.info("删除索引出现异常: {}", e);
        }
        return false;
    }

    public SearchResponse search(String indexName, SearchSourceBuilder searchSourceBuilder) throws IOException {
        SearchRequest searchRequest = new SearchRequest(indexName);
        searchRequest.source(searchSourceBuilder);
        return restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    }
}
